﻿using System;
using System.Collections.Concurrent;
using System.Transactions;
using ConferenceMessages;
using RockBus.ServiceBus;

namespace InternalConferenceManagementSystem
{
    public class InternalConferenceManagementService : IMessageProcessor
    {
        public static ConcurrentDictionary<string, ConferenceInfo> Conferences = new ConcurrentDictionary<string, ConferenceInfo>();

        public InternalConferenceManagementService()
        {
            this.PublisherClient = new PublisherClient();
            this.PublisherClient.ScanAssemblies(typeof(ConferenceInfo).Assembly);
        }

        private PublisherClient PublisherClient { get; set; }

        public ConferenceInfo CreateConference(CreateConferenceRequest request)
        {
            var ci = new ConferenceInfo(request.ConferenceId, request.UserId);
            Conferences.TryAdd(ci.ConferenceId, ci);

            ci = Conferences[ci.ConferenceId];
            Console.WriteLine("Conference created: {0}", ci.ToString());
            return ci;
        }

        public ConferenceInfo TerminateConference(TerminateConferenceRequest request)
        {
            ConferenceInfo ci = null;
            if (Conferences.TryRemove(request.ConferenceId, out ci))
            {
                ci.ConferenceStatus = ConferenceStatusEnum.Terminated;
                ci.Timestamp = DateTime.UtcNow;
            }
            else
            {
                ci = new ConferenceInfo(request.ConferenceId, request.UserId);
                ci.ConferenceStatus = ConferenceStatusEnum.Terminated;
            }

            Console.WriteLine("Conference terminated: {0}", ci.ToString());
            return ci;
        }

        public ConferenceInfo GetConferenceStatus(GetConferenceStatusRequest request)
        {
            var ci = Conferences[request.ConferenceId];
            return ci;
        }

        public void ProcessMessage(object message, Transaction transaction, Action<object> responseCallback)
        {
            if (message is CreateConferenceRequest)
            {
                var resp = this.CreateConference(message as CreateConferenceRequest);
                this.PublisherClient.Publish(resp);
            }

            else if (message is TerminateConferenceRequest)
            {
                var resp = this.TerminateConference(message as TerminateConferenceRequest);
                this.PublisherClient.Publish(resp);
            }

            else if (message is GetConferenceStatusRequest)
            {
                var resp = this.GetConferenceStatus(message as GetConferenceStatusRequest);
                this.PublisherClient.Publish(resp);
            }
        }
    }
}
